package com.eshop.api;

import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.alibaba.fastjson.annotation.JSONField;
import java.util.Date;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;

public class ApiResult<T> implements Serializable
{
    private static final long serialVersionUID = 8004487252556526569L;
    @ApiModelProperty("响应码")
    private int status;
    @ApiModelProperty("是否成功：成功true，失败false")
    private boolean success;
    @ApiModelProperty("响应消息")
    private String msg;
    @ApiModelProperty("响应数据")
    private T data;
    @ApiModelProperty("响应时间")
    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date time;
    
    public ApiResult() {
        this.time = new Date();
    }
    
    public static ApiResult<Boolean> result(final boolean flag) {
        if (flag) {
            return ok();
        }
        return fail();
    }
    
    public static ApiResult<Boolean> result(final ApiCode apiCode) {
        return result(apiCode, (Boolean)null);
    }
    
    public static <T> ApiResult<T> result(final ApiCode apiCode, final T data) {
        return result(apiCode, null, data);
    }
    
    public static <T> ApiResult<T> result(final ApiCode apiCode, String message, final T data) {
        boolean success = false;
        if (apiCode.getCode() == ApiCode.SUCCESS.getCode()) {
            success = true;
        }
        if (StringUtils.isBlank(message)) {
            message = apiCode.getMessage();
        }
        return (ApiResult<T>) builder().status(apiCode.getCode()).msg(message).data(data).success(success).time(new Date()).build();
    }
    
    public static ApiResult<Boolean> ok() {
        return ok((Boolean)null);
    }
    
    public static <T> ApiResult<T> ok(final T data) {
        return result(ApiCode.SUCCESS, data);
    }
    
    public static <T> ApiResult<T> ok(final T data, final String message) {
        return result(ApiCode.SUCCESS, message, data);
    }
    
    public static ApiResult<Map<String, Object>> okMap(final String key, final Object value) {
        final Map<String, Object> map = new HashMap<String, Object>(1);
        map.put(key, value);
        return ok(map);
    }
    
    public static ApiResult<Boolean> fail(final ApiCode apiCode) {
        return result(apiCode, (Boolean)null);
    }
    
    public static ApiResult<String> fail(final String message) {
        return result(ApiCode.FAIL, message, (String)null);
    }
    
    public static <T> ApiResult<T> fail(final ApiCode apiCode, final T data) {
        if (ApiCode.SUCCESS == apiCode) {
            throw new RuntimeException("失败结果状态码不能为" + ApiCode.SUCCESS.getCode());
        }
        return (ApiResult<T>)result(apiCode, (Object)data);
    }
    
    public static ApiResult<String> fail(final Integer errorCode, final String message) {
        return new ApiResult<String>().setSuccess(false).setStatus(errorCode).setMsg(message);
    }
    
    public static ApiResult<Map<String, Object>> fail(final String key, final Object value) {
        final Map<String, Object> map = new HashMap<String, Object>(1);
        map.put(key, value);
        return result(ApiCode.FAIL, map);
    }
    
    public static ApiResult<Boolean> fail() {
        return fail(ApiCode.FAIL);
    }
    
    public static <T> ApiResultBuilder<T> builder() {
        return new ApiResultBuilder<T>();
    }
    
    public int getStatus() {
        return this.status;
    }
    
    public boolean isSuccess() {
        return this.success;
    }
    
    public String getMsg() {
        return this.msg;
    }
    
    public T getData() {
        return this.data;
    }
    
    public Date getTime() {
        return this.time;
    }
    
    public ApiResult<T> setStatus(final int status) {
        this.status = status;
        return this;
    }
    
    public ApiResult<T> setSuccess(final boolean success) {
        this.success = success;
        return this;
    }
    
    public ApiResult<T> setMsg(final String msg) {
        this.msg = msg;
        return this;
    }
    
    public ApiResult<T> setData(final T data) {
        this.data = data;
        return this;
    }
    
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    public ApiResult<T> setTime(final Date time) {
        this.time = time;
        return this;
    }
    
    @Override
    public boolean equals(final Object o) {
        if (o == this) {
            return true;
        }
        if (!(o instanceof ApiResult)) {
            return false;
        }
        final ApiResult<?> other = (ApiResult<?>)o;
        if (!other.canEqual(this)) {
            return false;
        }
        if (this.getStatus() != other.getStatus()) {
            return false;
        }
        if (this.isSuccess() != other.isSuccess()) {
            return false;
        }
        final Object this$msg = this.getMsg();
        final Object other$msg = other.getMsg();
        Label_0091: {
            if (this$msg == null) {
                if (other$msg == null) {
                    break Label_0091;
                }
            }
            else if (this$msg.equals(other$msg)) {
                break Label_0091;
            }
            return false;
        }
        final Object this$data = this.getData();
        final Object other$data = other.getData();
        Label_0128: {
            if (this$data == null) {
                if (other$data == null) {
                    break Label_0128;
                }
            }
            else if (this$data.equals(other$data)) {
                break Label_0128;
            }
            return false;
        }
        final Object this$time = this.getTime();
        final Object other$time = other.getTime();
        if (this$time == null) {
            if (other$time == null) {
                return true;
            }
        }
        else if (this$time.equals(other$time)) {
            return true;
        }
        return false;
    }
    
    protected boolean canEqual(final Object other) {
        return other instanceof ApiResult;
    }
    
    @Override
    public int hashCode() {
        final int PRIME = 59;
        int result = 1;
        result = result * 59 + this.getStatus();
        result = result * 59 + (this.isSuccess() ? 79 : 97);
        final Object $msg = this.getMsg();
        result = result * 59 + (($msg == null) ? 43 : $msg.hashCode());
        final Object $data = this.getData();
        result = result * 59 + (($data == null) ? 43 : $data.hashCode());
        final Object $time = this.getTime();
        result = result * 59 + (($time == null) ? 43 : $time.hashCode());
        return result;
    }
    
    @Override
    public String toString() {
        return "ApiResult(status=" + this.getStatus() + ", success=" + this.isSuccess() + ", msg=" + this.getMsg() + ", data=" + this.getData() + ", time=" + this.getTime() + ")";
    }
    
    public ApiResult(final int status, final boolean success, final String msg, final T data, final Date time) {
        this.status = status;
        this.success = success;
        this.msg = msg;
        this.data = data;
        this.time = time;
    }
    
    public static class ApiResultBuilder<T>
    {
        private int status;
        private boolean success;
        private String msg;
        private T data;
        private Date time;
        
        ApiResultBuilder() {
        }
        
        public ApiResultBuilder<T> status(final int status) {
            this.status = status;
            return this;
        }
        
        public ApiResultBuilder<T> success(final boolean success) {
            this.success = success;
            return this;
        }
        
        public ApiResultBuilder<T> msg(final String msg) {
            this.msg = msg;
            return this;
        }
        
        public ApiResultBuilder<T> data(final T data) {
            this.data = data;
            return this;
        }
        
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
        public ApiResultBuilder<T> time(final Date time) {
            this.time = time;
            return this;
        }
        
        public ApiResult<T> build() {
            return new ApiResult<T>(this.status, this.success, this.msg, this.data, this.time);
        }
        
        @Override
        public String toString() {
            return "ApiResult.ApiResultBuilder(status=" + this.status + ", success=" + this.success + ", msg=" + this.msg + ", data=" + this.data + ", time=" + this.time + ")";
        }
    }
}
